package Saboteur;

import java.util.ArrayList;
import java.util.Random;

import eis.exceptions.ActException;
import Agent.AgentBase;
import Agent.Connexion;
import Perception.PerceptsBase;
import Perception.Percepts;
import Agent.ActionBehaviour;
import Agent.Util;

/**
 * TODO description
 */
public class RandomBehaviourSab extends ActionBehaviour{
	
	private AgentBase ag;
	private PerceptsBase percepts;
	private Connexion con;
	private boolean verbose;
	
	public RandomBehaviourSab(AgentBase ag, PerceptsBase percepts, Connexion con, boolean verbose)
	{
		super(ag,con);
		this.percepts = percepts;
		this.verbose = verbose;
	}
	
	public void action() {
		
		try
		{
			if(!ag.actionToDo())
				return;
			boolean move = true;
			if(verbose)
				ag.println(" name ");
			Percepts state = percepts.getPercepts("state").get(0);
			if(verbose)
				ag.println("...");
			if(state.getParam("lastActionResult").getValue().equals("failed_resources"))
			{
				if(verbose)
					ag.println("Pas assez d'energie -> Recharge");
				performAction(Util.rechargeAction());
				return;
			}
			else if(percepts.perceptsExists("visibleEntity"))
			{
				for(Percepts p : percepts.getPercepts("visibleEntity"))
				{
					String team = (String)(p.getParam("team").getValue());
					String status = (String)(p.getParam("status").getValue());
					String node = (String)(p.getParam("node").getValue());
					
					if(!team.equals(ag.getTeamName()) && ! status.equals("disabled"))
					{
						if(!inRange(node))
							continue;
						else
						{
							if(verbose)
								ag.println("INRANGE "+node);
						}
						String target = (String)(p.getParam("name").getValue());
						if(verbose)
							ag.println("Attaque "+target);
						performAction(Util.attackAction(target));
						return;
					}
				}
			}
		
			String n = Walk();
			if(verbose)
				ag.println("Deplacement vers "+n);
			performAction(Util.gotoAction(n));

		}
		catch(ActException e)
		{
			ag.println("Exception "+e.getMessage());
		}
	}
	
	@Override
	public boolean done() {
		// TODO Auto-generated method stub
		return false;
	}
	
	private String Walk() {

		ArrayList<Percepts> list = percepts.getPercepts("visibleEdge");
		String pos = (String)(percepts.getPercepts("state").get(0).getParam("position").getValue());
		
		ArrayList<String> noeuds  = new ArrayList<String>();
		Random rand = new Random(System.currentTimeMillis());
		
		int nbNoeud = 0;
		
		for(Percepts p : list)
		{
			if(p.getParam("node1").getValue().equals(pos))
			{
				nbNoeud++;
				noeuds.add((String)(p.getParam("node2").getValue()));
			}
			else if(p.getParam("node2").getValue().equals(pos))
			{
				nbNoeud++;
				noeuds.add((String)(p.getParam("node1").getValue()));
			}
		}
		
		int i = Math.abs(rand.nextInt())% nbNoeud;
		return noeuds.get(i);
		
	}
	
	public boolean inRange(String posT)
	{
		ArrayList<Percepts> list = percepts.getPercepts("visibleEdge");
		String pos = (String)(percepts.getPercepts("state").get(0).getParam("position").getValue());
		int range = Integer.parseInt((String)(percepts.getPercepts("state").get(0).getParam("visRange").getValue()));
		if(verbose)
			ag.println("pos ->  "+pos);
		for(Percepts p : list)
		{
			String node1 =(String)(p.getParam("node1").getValue());
			String node2 =(String)(p.getParam("node2").getValue());
			if((node1.equals(pos) && node2.equals(posT) )|| (node2.equals(pos) && node1.equals(posT)))
				return true;
			
			if(node1.equals(pos))
			{
				ArrayList<String> l = new ArrayList<String>();
				l.add(pos);
				if(inRange(posT, pos, range-1, l))
				{
					if(verbose)
						for(String s : l)
							ag.println(s);
					return true;
				}
			}
			else if(node2.equals(pos))
			{
				ArrayList<String> l = new ArrayList<String>();
				l.add(pos);
				if(inRange(posT, pos, range-1, l))
				{
					if(verbose)
						for(String s : l)
							ag.println(s);
					return true;
				}
			}
		}
		return false;
	}
	
	private boolean inRange(String posT,String posA,int range, ArrayList<String> noeuds)
	{
		ArrayList<Percepts> list = percepts.getPercepts("visibleEdge");
		
		for(Percepts p : list)
		{
			String node1 =(String)(p.getParam("node1").getValue());
			String node2 =(String)(p.getParam("node2").getValue());
			
			if(     (node1.equals(posA) && node2.equals(posT))||
					(node2.equals(posA) && node1.equals(posT)))
				return true;
			if(range == 0)
				continue;
			
			if(node1.equals(posA) && !noeuds.contains(node2))
			{
				noeuds.add(node2);
				if(inRange(posT, node2, range-1, noeuds))
				{
					return true;
				}
			}
			if(node2.equals(posA) && !noeuds.contains(node1))
			{
				noeuds.add(node1);
				if(inRange(posT, node1, range-1, noeuds))
					return true;
			}
			
		}
		return false;
	}
	
	
}